<template>
  <div class="app-container">
    <div class="app-container-flex">
      <div class="left-container">
        <div class="left-container-header border-style-bottom">
          <el-button
            v-if="proxy.$permission('deptSettingClassification:add')"
            :plain="true"
            :disabled="addBtn"
            @click="create"
            >{{ $t('btn_add') }}</el-button
          >
          <el-button
            v-if="proxy.$permission('deptSettingClassification:delete')"
            :plain="true"
            :disabled="addBtn || categoryId === -1"
            @click="deleteClass"
            >删除</el-button
          >
          <el-button
            v-if="proxy.$permission('deptSettingClassification:export')"
            :plain="true"
            @click="exportDeptClassificationExcel()"
            >导出excel</el-button
          >
          <el-upload
            :headers="uploadInfo.headers"
            :show-file-list="false"
            :on-error="uploadError"
            :on-success="importProduct"
            :before-upload="beforeProductUpload"
            :action="uploadInfo.action"
          >
            <el-button
              v-if="proxy.$permission('deptSettingClassification:import')"
              >导入</el-button
            >
          </el-upload>
          <el-button
            v-if="proxy.$permission('deptSettingClassification:import')"
            :plain="true"
            @click="downloadTemplate('dept_classification_import')"
            >下载导入模板</el-button
          >
        </div>
        <div class="left-container-header border-style-bottom">
          <el-input
            v-model="treeFilter.query.keyword"
            style="width: 200px; margin-left: 10px"
            :clearable="true"
            placeholder="请输入分类名称/编码"
            @keyup.enter="init"
          ></el-input>
          <el-button :plain="true" @click="init">搜索</el-button>
        </div>
        <div class="left-container-main main-flex">
          <el-tree
            ref="menuTree"
            :data="treeInfo.data"
            highlight-current
            :props="treeInfo.defaultProps"
            :default-expanded-keys="treeInfo.treeData"
            node-key="id"
            :default-checked-keys="[treeInfo.checked]"
            :default-expand-all="false"
            :expand-on-click-node="false"
            @node-click="handleNodeClick"
          />
        </div>
      </div>
      <div class="right-container">
        <div class="layui-card-body">
          <div class="model-panel">
            <!-- 条件栏 -->
            <page-filter
              v-model:query="filterInfo.query"
              :filter-list="filterInfo.list"
            >
              <template v-slot:filter-remove>
                <el-button
                  v-if="proxy.$permission('deptSettingClassification:delete')"
                  :disabled="canDelete"
                  @click="batchDelete"
                  >删除</el-button
                >
              </template>
            </page-filter>
            <!-- 表格 -->
            <table-container
              :refresh="tableInfo.refresh"
              :init-curpage="tableInfo.initCurpage"
              v-model:data="tableInfo.data"
              :api="tableInfo.api"
              :tab-index="true"
              :check-box="true"
              v-model:query="filterInfo.query"
              :field-list="tableInfo.fieldList"
              :handle="tableInfo.handle"
              @handleEvent="handleEvent"
            ></table-container>
          </div>
        </div>
      </div>
    </div>
    <!-- 新增修改弹窗 -->
    <page-dialog
      v-if="dialogInfo.visible"
      :title="dialogInfo.title[dialogInfo.type]"
      v-model:visible="dialogInfo.visible"
      :width="dialogInfo.width"
      :bt-loading="dialogInfo.btLoading"
      :bt-list="dialogInfo.btList"
    >
      <!-- form -->
      <page-form
        class="paddingBox order-model-formBox flex_wrap_start_start"
        v-model:ref-obj="formInfo.ref"
        :data="formInfo.data"
        :field-list="formInfo.fieldList"
        :rules="formInfo.rules"
        :label-width="formInfo.labelWidth"
      />
    </page-dialog>
  </div>
</template>

<script setup name="departmentInformation">
import {
  getDeptClassificationTree,
  addDeptClassification,
  updateDeptClassification,
  deleteDeptClassificationByIds,
  exportDeptClassification,
  getDeptClassificationPage,
} from '@/api/core'
import { ElLoading } from 'element-plus'
import { exportTemplateExcel } from '@/api/pub'
import axios from 'axios'

const { proxy } = getCurrentInstance()
const treeFilter = ref({
  query: {
    keyword: '',
  },
})
// 过滤相关配置
const filterInfo = ref({
  query: {},
  list: [
    {
      type: 'slot',
      value: 'remove',
      show: true,
    },
    {
      type: 'input',
      label: '名称',
      value: 'nameLike',
      event: search,
    },
    {
      type: 'input',
      label: '编码',
      value: 'codeLike',
      event: search,
    },
    { type: 'button', label: '搜索', event: search },
    { type: 'button', label: '重置', event: clearSearch },
  ],
})
const uploadInfo = ref({
  action: axios.defaults.baseURL + '/core/dept/classification/import/excel',
  headers: {
    Authorization: proxy.$store.state.user.token,
  },
  loading: {},
})
const addBtn = ref(true) //控制左侧树节点上方新增按钮状态
const saveBtn = ref(true)
// 权限树
const treeInfo = ref({
  data: [],
  nodeKey: 'code',
  checked: [],
  treeData: [],
  defaultProps: {
    children: 'children',
    label: 'name',
  },
})
const tableInfo = ref({
  refresh: 1,
  initCurpage: 1,
  data: [],
  api: getDeptClassificationPage,
  fieldList: [
    {
      label: '名称',
      value: 'name',
    },
    {
      label: '编码',
      value: 'code',
    },
    {
      label: '上级分类',
      value: 'parentName',
    },
    {
      label: '备注',
      value: 'remark',
    },
  ],
  handle: {
    fixed: 'right',
    label: '操作',
    width: '90',
    btList: [
      {
        label: '修改',
        event: update,
        show: proxy.$permission('assetClassify:update'),
      },
      {
        label: '删除',
        event: remove,
        show: proxy.$permission('assetClassify:delete'),
      },
    ],
  },
})
// 弹窗相关
const dialogInfo = ref({
  title: {
    create: '新增',
    update: '修改',
  },
  visible: false,
  type: '',
  width: '40%',
  btLoading: false,
  btList: [
    { label: '关闭', type: '', icon: '', event: close, show: true },
    {
      label: '保存',
      type: 'primary',
      icon: '',
      event: save,
      saveLoading: false,
      show: true,
    },
  ],
})
// 表单相关
const formInfo = ref({
  ref: null,
  data: {},
  fieldList: [
    {
      label: '名称',
      value: 'name',
      type: 'input',
      maxlength: 50,
      required: true,
    },
    {
      label: '父级编码',
      value: 'parentCode',
      type: 'input',
      disabled: true,
      required: false,
    },
    {
      label: '编码',
      value: 'code',
      type: 'input',
      maxlength: 32,
      required: true,
    },
    {
      label: '备注',
      value: 'remark',
      type: 'textarea',
      maxlength: 200,
      required: false,
    },
  ],
  rules: {
    name: [{ required: true, message: '请输入名称', trigger: 'blur' }],
    code: [
      { required: true, message: '请输入编码', trigger: 'blur' },
      { validator: proxy.$validate.validatEn, trigger: 'blur' },
    ],
  },
  labelWidth: '130px',
})
const selectRows = ref([])
const addOrUpdate = ref('')
const RightBox = ref(false)
const categoryId = ref('')
const isAddUpdate = ref('add')
const selectSettingCategoryInfo = ref({
  visible: false,
  saveEmpty: true,
  query: {},
})
const selectInfo = ref({
  visible: false,
  saveEmpty: true,
  query: {},
})
const selectRow = ref({})
const canCreate = computed(() => {
  return addBtn.value
})
const canDelete = computed(() => {
  return selectRows.value.length <= 0
})
const canUpdate = computed(() => {
  return dialogInfo.value.type == 'update' ? true : false
})
watch(
  () => treeInfo.value.data,
  () => {
    RightBox.value = false

    addBtn.value = true
    saveBtn.value = true
  },
  {
    deep: true,
  }
)
onMounted(() => {
  init()
})
function init() {
  getDeptClassificationTree(treeFilter.value.query).then((res) => {
    if (res && res.success) {
      let data = [res.data]
      treeInfo.value.data = data
      if (treeFilter.value.query.keyword) {
        treeInfo.value.treeData = []
        getNodeId(data, -1)
      } else {
        treeInfo.value.treeData = []
        getNodeId(data, 2)
      }
    }
  })
}
function getNodeId(data, num, count = 0) {
  count++
  data.forEach((item) => {
    if (count === num) {
      return
    }
    treeInfo.value.treeData.push(item.id)
    if (item.children && item.children.length) {
      getNodeId(item.children, num, count)
    }
  })
}

// 搜索
function search() {
  // 重置分页
  tableInfo.value.initCurpage = Math.random()
  tableInfo.value.refresh = Math.random()
}
function clearSearch() {
  tableInfo.value.data = []
  filterInfo.value.query = {}
  search()
}
function addClass() {
  addOrUpdate.value = addDeptClassification
  isAddUpdate.value = 'add'
  RightBox.value = false
  depreciationInfo.value.data = {}
  saveBtn.value = false
}
// 删除分类
function deleteClass() {
  proxy
    .$confirm('删除该分类会清空所有的子分类,确认删除该分类吗？', '提示', {
      confirmButtonText: '确定',
      cancelButtonText: '取消',
      type: 'warning',
    })
    .then(() => {
      let select = proxy.$refs.menuTree.getCurrentNode()
      let id = select.id //当前节点id

      let arr = []
      arr.push(id)
      deleteDeptClassificationByIds(arr).then((res) => {
        if (res.success) {
          init()
          filterInfo.value.query = {}
          search()
          isAddUpdate.value = 'add'
        }
      })
    })
    .catch(() => {})
}
// 点击树节点
function handleNodeClick(node) {
  if (node.id !== -1) {
    filterInfo.value.query.parentCode = node.code
  } else {
    filterInfo.value.query.parentCode = ''
  }
  search()
  addBtn.value = false
  categoryId.value = node.id
}
function handleEvent(event, data) {
  switch (event) {
    case 'tableCheck':
      selectRows.value = data
      break
  }
}
function uploadError(err) {
  if (err) {
    proxy.$message.error('系统错误')
  }
  uploadInfo.value.loading.close()
}
function beforeProductUpload(file) {
  //发生请求时打开加载动画
  uploadInfo.value.loading = ElLoading.service({
    fullscreen: true,
    background: 'rgba(255,255,255,.4)',
  })
  let fileType = ['xlsx']
  let fileSize = proxy.$store.state.permission.systemConfig.max_file_size
  let isFileType = fileType.some(
    (type) => file.name.split('.')[file.name.split('.').length - 1] === type
  )
  const isLt = file.size / 1024 / 1024 < fileSize
  if (!isFileType) {
    proxy.$message.error({
      message: `文件格式不正确, 请上传 ${fileType.join(' / ')} 格式文件!`,
      showClose: true,
      duration: 3500,
    })
    uploadInfo.value.loading.close()
    return false
  }
  if (!isLt) {
    proxy.$message.error({
      message: `上传文件大小不能超过 ${fileSize} MB!`,
      showClose: true,
      duration: 3500,
    })
    uploadInfo.value.loading.close()
    return false
  }
  return isFileType && isLt
}
function importProduct(resp) {
  uploadInfo.value.loading.close()
  if (resp && resp.success) {
    proxy.$message.success({
      duration: 3000,
      showClose: true,
      message: resp.msg,
    })
    init()
    filterInfo.value.query = {}
    search()
  } else {
    proxy.$message.error({
      message: resp.msg,
      duration: 0,
      showClose: true,
    })
  }
}
function exportDeptClassificationExcel() {
  exportDeptClassification().then((resp) => {
    if (resp) {
      proxy.$fn.parseExcel(resp)
    }
  })
}
function downloadTemplate(tag) {
  exportTemplateExcel(tag).then((res) => {
    if (res) {
      proxy.$fn.parseExcel(res)
    }
  })
}
// 创建
function create() {
  formInfo.value.fieldList[2].disabled = false
  formInfo.value.data = {}
  dialogInfo.value.type = 'create'
  let parent = proxy.$refs.menuTree.getCurrentNode()
  formInfo.value.data.parentCode = parent.code
  dialogInfo.value.visible = true
}
// 编辑
function update(data) {
  formInfo.value.fieldList[2].disabled = true
  isAddUpdate.value = 'update'
  dialogInfo.value.type = 'update'
  dialogInfo.value.visible = true
  // 显示信息
  formInfo.value.data = { ...data }
  formInfo.value.data.parentCode = data.code.substring(0, data.code.length - 2)
}
function remove(node) {
  proxy
    .$confirm('删除该分类会清空所有的子分类,确认删除该分类吗？', '提示', {
      confirmButtonText: '确定',
      cancelButtonText: '取消',
      type: 'warning',
    })
    .then(() => {
      let arr = []
      arr.push(node.id)
      deleteDeptClassificationByIds(arr).then((res) => {
        if (res.success) {
          init()
          search()
          isAddUpdate.value = 'add'
        }
      })
    })
    .catch(() => {})
}
function save() {
  formInfo.value.ref.validate((valid) => {
    if (valid) {
      let api
      const params = formInfo.value.data
      const type = dialogInfo.value.type
      if (type === 'create') {
        api = addDeptClassification
      } else if (type === 'update') {
        api = updateDeptClassification
      } else {
        return
      }
      let parent = params.parentCode
      if (parent === 'root') {
        if (params.code.length != 2) {
          proxy.$message({
            message:
              '第一层的编码[' + params.code + ']长度必须为两位，请修改！',
            type: 'error',
            duration: 3500,
            showClose: true,
          })
          return
        }
      } else {
        if (params.code.length - 2 != parent.length) {
          proxy.$message({
            message:
              '当前编码[' +
              params.code +
              ']长度应等于父级编码[' +
              parent +
              ']的长度加二，请修改！',
            type: 'error',
            duration: 3500,
            showClose: true,
          })
          return
        }
        if (params.code.substring(0, parent.length) != parent) {
          proxy.$message({
            message:
              '当前编码[' +
              params.code +
              ']头部与父级编码[' +
              parent +
              ']不匹配，请修改！',
            type: 'error',
            duration: 3500,
            showClose: true,
          })
          return
        }
        params.submitCode = parent
      }
      dialogInfo.value.btLoading = true
      proxy
        .$handleAPI(type, api, params)
        .then((res) => {
          if (res.success) {
            dialogInfo.value.visible = false
            tableInfo.value.refresh = Math.random()
            init()
          }
          dialogInfo.value.btLoading = false
        })
        .catch((e) => {
          dialogInfo.value.btLoading = false
        })
    }
  })
}
function close() {
  dialogInfo.value.visible = false
  formInfo.value.data = {}
}
function batchDelete() {
  proxy
    .$confirm('删除该分类会清空所有的子分类,确认删除该分类吗？', '提示', {
      confirmButtonText: '确定',
      cancelButtonText: '取消',
      type: 'warning',
    })
    .then(() => {
      let arr = []
      if (selectRows.value.length != 0) {
        selectRows.value.forEach((row) => {
          arr.push(row.id)
        })
      }
      deleteDeptClassificationByIds(arr).then((res) => {
        if (res.success) {
          init()
          search()
          isAddUpdate.value = 'add'
        }
      })
    })
    .catch(() => {})
}
</script>

<style lang="scss" scoped>
.app-container {
  height: calc(100vh - 83px);
}
.left-container {
  min-width: 350px;
  .left-container-header {
    display: flex;
    justify-content: space-around;
    padding: 10px 0;
  }
  .border-style-bottom {
    margin-bottom: 0;
  }
}
.main-flex {
  flex-grow: 1;
  display: flex;
  flex-wrap: nowrap;
  height: calc(100% - 120px);
  .el-tree {
    width: 100%;
    padding: 0 20px 20px;
    overflow-y: auto;
  }
}
</style>
